////////////////////////////////////////////////////////////////
//
//						FAT16 Functions
//				Undergraduate Student Project
//		Instrumentation, Robotics, and Control Laboratory
//
//Group:	MotesArt 2
//Author:	Bernard James U. Tan
//modified, simplified and expanded from:
//Group: 	Axel Activity Monitor Phase 2
//Author:	Stephen Alfred K. Quedi
//
////////////////////////////////////////////////////////////////

#include <ez8.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "mmc.h"
#include "fat.h"

unsigned char FATentries[512];
unsigned short FATcounter;
unsigned long int FATaddressincrement;	//the increment is used so it can be used for both FAT1 and FAT2
unsigned char FAThigh;
unsigned char FATlow;					//these two are used if a file is larger than one cluster
unsigned char CSV_file[512];
unsigned short CSVcounter;
unsigned long int CSVaddress;
unsigned char DATAarray[512];
unsigned short DATAcounter;
unsigned long int DATAaddress;
unsigned long int DATAsectorcount;			//incremented every 512 bytes, bec 512bytes/sector, also used for to know cluster count: 16sectors/cluster
unsigned long int DATAsectorcountflag=0;

void format_to_fat16 (void)					//format function
{		// this is for 2GB
unsigned char buffer[512]={	//BPB_FAT16
0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x40,0x02,0x00,
0x02,0x00,0x02,0x00,0x00,0xF8,0xEB,0x00,0x3F,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
0x00,0xA0,0x3A,0x00,0x80,0x00,0x29,0xF5,0x1D,0x60,0xC8,0x4E,0x4F,0x20,0x4E,0x41,
0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,0x33,0xC9,
0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
0xB0,0x42,0x4F,0x4F,0x54,0x4D,0x47,0x52,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA};
	unsigned long i,j;
	unsigned int err=0;
	unsigned long int temporary;
	char errorprinted=0;
	PDOUT |= 0x01;								//symbolyzes error, LED1 on
	do{
		err=InitMMC(); 								//Initialize SPI ports to be used for MMC		
		printf("err = %d",err);
		if (err==0){
			err=WriteMMC(start_address,buffer);		//From Experiment, if connection is not okay, it waits here		
			ReadMMC(start_address,buffer);
			if (buffer[0]!=0xEB) err++;
			if (buffer[1]!=0x3C) err++;
			if (buffer[2]!=0x90) err++;
			if (buffer[3]!=0x4D) err++;
			if (buffer[510]!=0x55) err++;
			if (buffer[511]!=0xAA) err++;
			if ((err>0)&&(errorprinted==0)){
				PDOUT |= 0x01;						//LED to show it can't write
				errorprinted=1;
				printf("I Can't Write.");
			}
		}
	}while (err>0);
	err=0;
	errorprinted=0;
	PDOUT &= ~0x01;								//LED1 off, shows it passed through the first write
	for(i=0;i<512;i++) buffer[i]=0;
	for(i=512;i<data_region_addr;i+=512){
		err=WriteMMC(i,buffer); //clean all address after BPB&before dataregion
		if (i%5120==0){
			printf(".");
			PDOUT ^= 0x01;
			}
	}
	FATentries[0]=0xF8;						//initialize FATentries 0xF8 0xFF 0xFF 0xFF then 0 up to the end
	for (i=1;i<4;i++) FATentries[i]=0xFF;
	for (;i<512;i++) FATentries[i]=0;
	do{
		err=0;
		err=InitMMC(); 								//Initialize SPI ports to be used for MMC
		if (err==0){
			err=WriteMMC(FAT1_entries_start,FATentries);	//write FAT1 and FAT2, they are identical
			ReadMMC(FAT1_entries_start,buffer);
			for (i=0;i<4;i++){
				if (buffer[i]!=FATentries[i]){
					err=1;
					if (errorprinted==0){
						PDOUT ^= 0x03;						//LED to show it can't write
						errorprinted=1;
					}
				}
			}
		}
		printf("InitMMC loop.. ******\n");
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//LED1 off, shows it passed through the write
	for (i=0;i<4;i++) buffer[i]=0;				//clear buffer
	do{
		err=InitMMC(); 								//Initialize SPI ports to be used for MMC
		if (err==0){
			err=WriteMMC(FAT2_entries_start,FATentries);
			ReadMMC(FAT2_entries_start,buffer);
			for (i=0,err=0;i<4;i++){
				if (buffer[i]!=FATentries[i]){
					err=1;
					if (errorprinted==0){
						PDOUT |= 0x01;						//LED to show it can't write
						errorprinted=1;
					}
				}
			}
		}
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//LED1 off, shows it passed through the write
	for (i=0;i<512;i++) CSV_file[i]=0;			//clear array where root directory, thus CSVfiles are to be written
	i=0;
	CSV_file[i++]='M';							//put volume label of length of 11 or less
	CSV_file[i++]='M';
	CSV_file[i++]='C';
	CSV_file[i++]='_';
	CSV_file[i++]='T';
	CSV_file[i++]='E';
	CSV_file[i++]='S';
	CSV_file[i++]='T';
	CSV_file[i++]='\n';	//8th char
	for (;i<11;i++) CSV_file[i]=32;				//32 is space; put other data for it to be a volume label
	CSV_file[11]=8;
	do{
		err=InitMMC(); 								//Initialize SPI ports to be used for MMC
		if (err==0){
			err=WriteMMC(root_directory_addr,CSV_file);		//From Experiment, if connection is not okay, it waits here
			//printf("another wait..\n");
			ReadMMC(root_directory_addr,buffer);
			for (i=0,err=0;i<25;i++){
				if (buffer[i]!=CSV_file[i]){
					err=1;
					if (errorprinted==0){
						PDOUT |= 0x01;						//LED to show it can't write
						errorprinted=1;
					}
				}
			}
		}
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//LED1 off, shows it passed through the write
	DATAaddress=data_region_addr;
	return;
}

//root_directory_addr is the location of the folders and 
//foldercontents is where CSV filename written
unsigned long int foldercontentsaddress=0;
unsigned char previousfolderhighbyte=0;
unsigned char previousfolderlowbyte=0;

unsigned char findlastfolder(void)
//return 0 if last folder found!
//return 1 if none
{
	unsigned short FstClusLO;					//used to compute the location of the data of the file in the data region
	unsigned char err=0;
	PDOUT |= 0x01;								//symbolyzes error, LED1 on
	do{
		err=InitMMC(); 							//Initialize SPI ports to be used for MMC
	}while (err>0);
	for (CSVaddress=root_directory_addr,CSVcounter=0;CSVcounter==0;CSVaddress+=512){ //updates global variable CSVaddress
		err=ReadMMC(CSVaddress,CSV_file);		//updates global variable CSV_file
		for (CSVcounter=0;CSVcounter<512;CSVcounter+=32){ //finds the first empty slot in every 32bits
			if (CSV_file[CSVcounter]==0) break;	//updates global variable CSVcounter
		}
		if (CSVcounter==512){
			CSVcounter=0;
		}
		if (CSV_file[CSVcounter]==0) break;
	}
	if (CSVcounter==0){
		CSVaddress-=512;
		if (CSVaddress<root_directory_addr) return 1;
		err=ReadMMC(CSVaddress,CSV_file);		//updates global variable CSV_file
		CSVcounter=512;
	}
	for (CSVcounter-=32;!((CSVaddress==root_directory_addr)&&(CSVcounter==0));CSVcounter-=32){
		if (CSV_file[CSVcounter+11]==16){					//found the last folder
			previousfolderhighbyte=CSV_file[CSVcounter+27];
			previousfolderlowbyte=CSV_file[CSVcounter+26];
			FstClusLO=previousfolderhighbyte*256+previousfolderlowbyte;
			foldercontentsaddress=(FstClusLO-2)*32768+data_region_addr; //8192=0x2000 (bytes in a cluster for 512mb mmc), because the first file have 2 as FstClusLO and dataregion 0x41000 // changed from 8192 to 16384 for 1gb mmc
			return 0;
		}else{
			if (CSVcounter==0) CSVaddress-=512;
		}
	}
	PDOUT &= ~0x01;								//LED1 off, shows it passed through the write
	return 1;
}

char filename[9];								//global so it can be used later in writetommc in MMDDYY
unsigned char create_folder_file(char * rawfilename, char inrootdir, char isfolder)
{
	char prevfilename[9];
	unsigned short FATgreaterthanonecluster;	//if the file is greater than one cluster, it will write this in the FAT entry
	unsigned short FstClusLO;					//used to compute the location of the data of the file in the data region
	unsigned int i=0,j=0,intdate;
	unsigned char err=0, nextblock=0;
	char tempdate[3]=0;		// string to be made to int
	char errorprinted=0;
	do{
		err=InitMMC();
		ReadMMC(FAT1_entries_start,FATentries);			//read FATentries just for checking
		if ((FATentries[0]==0)&&(errorprinted==0)){			//by experiment, readmmc returns 0 if no card,and we're sure that the first byte at start address is not 0
			PDOUT |= 0x01;						//LED to show it can't write
			errorprinted=1;
			return 1;							//return 1 for error
		}
	}while (FATentries[0]==0);
	errorprinted=0;
	PDOUT &= ~0x01;								//turn off the LED
	for (i=0;i<8;i++) filename[i]=rawfilename[i];
	if ((inrootdir==1)||(foldercontentsaddress==0)){ CSVaddress=root_directory_addr;}
	else {CSVaddress=foldercontentsaddress;}
	for (CSVcounter=0;CSVcounter==0;CSVaddress+=512){ //updates global variable CSVaddress
		if ((inrootdir==1)&&(CSVaddress>=data_region_addr)){
				PDOUT |= 0x01;	//blink a LED and stay here
				return 1;		//return 1 for error	
		}
		if ((inrootdir==0)&&(nextblock==64)){ //changed from 16 to 32 sectors per cluster for 1gb mmc
			create_folder_file(rawfilename,1,1);
			create_folder_file(rawfilename,inrootdir,isfolder);
			return 1;	//return 1 for error
		}
		err=ReadMMC(CSVaddress,CSV_file);		//updates global variable CSV_file
		for (CSVcounter=0;CSVcounter<512;CSVcounter+=32){ //finds the first empty slot in every 32bits
			if (CSV_file[CSVcounter]==0) break;	//updates global variable CSVcounter
		}
		if (CSVcounter==512){
			CSVcounter=0;
			nextblock++;
		}
		if (CSV_file[CSVcounter]==0) break;
	}
	if (CSVcounter==0){							//the new CSVfile in rootdirectory will be written in a new data block, can't use CSVcounter-32 later
		err=ReadMMC(CSVaddress-512,CSV_file);
		for (i=480,j=0;j<8;i++,j++) prevfilename[j]=CSV_file[i];
		prevfilename[j]=0;
		err=ReadMMC(CSVaddress,CSV_file);
	}else{
		err=ReadMMC(CSVaddress,CSV_file);
		for (i=CSVcounter-32,j=0;j<8;i++,j++) prevfilename[j]=CSV_file[i];
		prevfilename[j]=0;
	}
	for (j=0,err=0;j<6;j++){ //compare the first 6 bytes
		if (prevfilename[j]!=filename[j]) err=1;
	}											//err will be 1 if different, 0 if same, i at this instance is the location of the first appended bit
	if (err==0){
		if (prevfilename[7]=='9'){				//makes files from 00 to 99 then A0-9, B0-9, up to Z0-9
			filename[7]='0';
			if (prevfilename[6]=='9') filename[6]='A';
			else filename[6]=prevfilename[6]+1;
		}else{
			filename[7]=prevfilename[7]+1;
			filename[6]=prevfilename[6];
		}
	}else{
		filename[7]='0';
		filename[6]='0';
	}
	filename[8]=0;
	for (i=CSVcounter,j=0;((j<strlen(filename))&&(j<8));i++,j++) CSV_file[i]=filename[j]; //put filename
	for (;j<8;i++,j++) CSV_file[i]=32; //sp
	if (isfolder==0){
		CSV_file[i++]=67;	//C
		CSV_file[i++]=83;	//S
		CSV_file[i++]=86;	//V
		CSV_file[i]=32;	//Archive
	}else{
		for (;j<11;i++,j++) CSV_file[i]=32; //sp
		CSV_file[i]=16;	//Subdirectory or Folder type
	}
	i+=5;
	tempdate[0]=filename[2];	//day
	tempdate[1]=filename[3];
	tempdate[2]=0;
	intdate=atoi(tempdate);
	CSV_file[i]=intdate;
	tempdate[0]=filename[0];	//month
	tempdate[1]=filename[1];
	tempdate[2]=0;
	intdate=atoi(tempdate);
	if (intdate>=8){
		CSV_file[i+1]=1;
		intdate-=8;
	}
	CSV_file[i]=(intdate<<5)|(CSV_file[i]);
	CSV_file[i+2]=CSV_file[i];
	CSV_file[i+8]=CSV_file[i];
	tempdate[0]=filename[4];	//year
	tempdate[1]=filename[5];
	tempdate[2]=0;
	intdate=atoi(tempdate);
	intdate+=20;
	CSV_file[++i]=(intdate<<1)|CSV_file[i];
	CSV_file[i+2]=CSV_file[i];
	CSV_file[i+8]=CSV_file[i];
	FATaddressincrement=0;
	err=ReadMMC(FAT1_entries_start,FATentries); //from experiment, FATentries[511] will not be zero if the block is full
	for (;FATentries[511]!=0;){ //find the first not full 512 block in FAT1
		FATaddressincrement+=512;
		err=ReadMMC(FAT1_entries_start+FATaddressincrement,FATentries); //from experiment, FATentries[511] will not be zero if the block is full
	}	//updates global variables FATaddressincrement and FATentries at the same time and the for loop below updates FATcounter
	for (FATcounter=510;((FATentries[FATcounter-2]==0)&&(FATentries[FATcounter-1]==0)&&(FATcounter!=0));FATcounter-=2); //510 is the position of the last LO byte in a block
	FstClusLO=(FATaddressincrement+FATcounter)/2; //FstClusLO is just the distance from the start of fat entry
	CSV_file[CSVcounter+27]=FstClusLO/256;		//get the High Byte of j
	CSV_file[CSVcounter+26]=FstClusLO%256;		//low Byte of j
	FATgreaterthanonecluster=(FATaddressincrement+FATcounter+2)/2; //the counter for LowByte HighByte for FATentries larger than one cluster
	FAThigh=FATgreaterthanonecluster/256;		//High Byte for Fat counter
	FATlow=FATgreaterthanonecluster%256; 		//Low Byte for FAT counter
	for (i=0;i<512;i++) DATAarray[i]=0;			//initialize DATAarray to zero
	DATAcounter = 0;							//at the first byte
	DATAaddress=(FstClusLO-2)*32768+data_region_addr; //8192=0x2000 (bytes in a cluster for 512mb mmc), because the first file have 2 as FstClusLO and dataregion 0x41000 //changed from 8192 to 16384 for 1gb mmc
	DATAsectorcount=0;
	if (DATAaddress>=last_addr){
			PDOUT |= 0x02;	//light up a LED and stay here
			return 1;		//return 1 for error				
	}
	do{
		err=InitMMC();
		err=CSV_file[0];
		WriteMMC(CSVaddress,CSV_file);
		CSV_file[0]=0;
		ReadMMC(CSVaddress,CSV_file);
		if (CSV_file[0]!=err){
			if (errorprinted==0){
				PDOUT |= 0x01;						//LED to show it can't write
				errorprinted=1;
				return 1;							//return 1 for error
			}
			CSV_file[0]=err;					//so it will be back to the true
 		    err=1;
		}else{ err=0;}
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//turn off the LED
	if (isfolder==1){
		CSV_file[0]=0x2E;
		for (i=1;i<11;i++) CSV_file[i]=0x20;
		for (;i<32;i++) CSV_file[i]=CSV_file[CSVcounter+i];
		CSV_file[i++]=0x2E;
		CSV_file[i++]=0x2E;
		for (;i<43;i++) CSV_file[i]=0x20;
		for (;i<58;i++) CSV_file[i]=CSV_file[CSVcounter+i-32];
		if (!inrootdir){
			CSV_file[i++]=previousfolderhighbyte;
			CSV_file[i++]=previousfolderlowbyte;
		}
		previousfolderhighbyte=CSV_file[CSVcounter+27];
		previousfolderlowbyte=CSV_file[CSVcounter+26];
		for (;i<512;i++) CSV_file[i]=0;
		foldercontentsaddress=DATAaddress;
		do{
			err=InitMMC();
			err=CSV_file[0];
			WriteMMC(foldercontentsaddress,CSV_file);
			CSV_file[0]=0;
			ReadMMC(foldercontentsaddress,CSV_file);
			if (CSV_file[0]!=err){
				if (errorprinted==0){
					PDOUT |= 0x01;						//LED to show it can't write
					errorprinted=1;
					return 1;							//return 1 for error
				}
				CSV_file[0]=err;					//so it will be back to the true
 			    err=1;
			}else{ err=0;}
		}while (err==1);
		errorprinted=0;
		for (i=0;i<512;i++) CSV_file[i]=0;
		for (i=512;i<32768;i+=512) WriteMMC(foldercontentsaddress+i,CSV_file);	//8192 is 16*512 erase remaining bytes in one cluster // changed to 32*512 = 16384 for 1gb mmc
		FATentries[FATcounter++]=0xFF;			//FATcounter should not increment here
		FATentries[FATcounter++]=0xFF;			//nor here
		err=WriteMMC(FAT1_entries_start+FATaddressincrement,FATentries); //write FAT1 and FAT2, they are identical
		err=WriteMMC(FAT2_entries_start+FATaddressincrement,FATentries);
	}
	return 0;	//return 0 for no error
}

char writetommc(char *newdata, char *newfilename){
	unsigned int i;
	unsigned char err=0;
	unsigned char firstbyte=0;
	char errorprinted=0;
	char timeout=0;
	for (i=0;i<6;i++){
		if (filename[i]!=newfilename[i]){
			create_folder_file(newfilename,0,0);
			for (i=0;i<6;i++) filename[i]=newfilename[i];
			break;
		}
	}
	for (i=0;i<strlen(newdata);i++){
		if (((i==0)&&(newdata[i+1]==','))||(((newdata[i-1]==',')||(newdata[i-1]=='/')||(newdata[i-1]==':'))&&((newdata[i+1]==',')||(newdata[i+1]=='/')||(newdata[i+1]==':')||(newdata[i+1]==' ')))){
			DATAarray[DATAcounter++]='0';
		}
		if (DATAcounter==512) DATAfull();
		DATAarray[DATAcounter++]=newdata[i];
		if (DATAcounter==512) DATAfull();
	}
	do{
		err=InitMMC();
		err=DATAarray[0];
		WriteMMC(DATAaddress,DATAarray);
		DATAarray[0]=0;
		ReadMMC(DATAaddress,DATAarray);
		if (DATAarray[0]!=err){
			if (errorprinted==0){
				PDOUT |= 0x01;						//LED to show it can't write
				errorprinted=1;
			}
			DATAarray[0]=err;					//so it will be back to the true
			err=1;
		}else{ err=0;}
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//turn off the LED
	check_updateFAT();
	updateCSVsize();
	printf("written to mmc. \n");
	return 0;
}

void DATAfull(void){
	unsigned int i;
	unsigned char err=0,firstbyte;
	char errorprinted=0;
	do{
		err=InitMMC();
		err=DATAarray[0];
		WriteMMC(DATAaddress,DATAarray);
		DATAarray[0]=0;
		ReadMMC(DATAaddress,DATAarray);
		if (DATAarray[0]!=err){
			if (errorprinted==0){
				PDOUT |= 0x01;						//LED to show it can't write
				errorprinted=1;
			}
			DATAarray[0]=err;					//so it will be back to the true
			err=1;
		}else{ err=0;}
	}while (err==1);
	errorprinted=0;
	PDOUT &= ~0x01;								//turn off the LED
	DATAaddress+=512;
	if (DATAaddress>=last_addr){
		PDOUT |= 0x01;	//light up a LED and stay here
		printf("MEMORY FULL!\n");
		}
	for (i=0;i<512;i++) DATAarray[i]=0;			//initialize DATAarray to zero
	DATAcounter=0;
	DATAsectorcount++;
}

void check_updateFAT(void){
	unsigned int i;
	unsigned char err=0;
	if (((DATAsectorcount%64)==0)&&(DATAsectorcount!=DATAsectorcountflag)&&(DATAsectorcount>0)&&(DATAcounter>0)){	//FATcounter is only incremented after one cluster is written, for a 512mb,one cluster is 16sectors // for a 1gb, 32sectors
		DATAsectorcountflag=DATAsectorcount;
		FATentries[FATcounter++]=FATlow++;
		FATentries[FATcounter++]=FAThigh;
		if (FATlow==0) FAThigh++;
		if (FATcounter==512){
			err=WriteMMC(FAT1_entries_start+FATaddressincrement,FATentries); //write FAT1 and FAT2, they are identical
			err=WriteMMC(FAT2_entries_start+FATaddressincrement,FATentries);
			FATaddressincrement+=512;
			FATcounter=0;
			for (i=0;i<512;i++) FATentries[i]=0; //initialize FATentries to zero
		}
	}
	if ((FATentries[FATcounter]!=0xFF)||(FATentries[FATcounter+1]!=0xFF)){
		FATentries[FATcounter]=0xFF;			//FATcounter should not increment here
		FATentries[FATcounter+1]=0xFF;			//nor here
		err=WriteMMC(FAT1_entries_start+FATaddressincrement,FATentries); //write FAT1 and FAT2, they are identical
		err=WriteMMC(FAT2_entries_start+FATaddressincrement,FATentries);
	}	//else do nothing
}

void updateCSVsize(void){	//4bytes at the last of the 32 bytes CSV file in the root directory
	unsigned long int temp=DATAsectorcount;
	unsigned char err=0;
	int i;
	CSV_file[CSVcounter+31]=temp/32768;			//highest byte
	temp=temp%32768;
	CSV_file[CSVcounter+30]=temp/128;			//2nd highest byte
	temp=temp%128;
	CSV_file[CSVcounter+29]=temp*2+DATAcounter/256; //3rd
	CSV_file[CSVcounter+28]=DATAcounter%256;	//lowest byte
	err=WriteMMC(CSVaddress,CSV_file);
}

